<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">


<script id="hexo-configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    hostname: new URL('http://yoursite.com').hostname,
    root: '/',
    scheme: 'Pisces',
    version: '7.6.0',
    exturl: false,
    sidebar: {"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},
    copycode: {"enable":false,"show_result":false,"style":null},
    back2top: {"enable":true,"sidebar":false,"scrollpercent":false},
    bookmark: {"enable":false,"color":"#222","save":"auto"},
    fancybox: false,
    mediumzoom: false,
    lazyload: false,
    pangu: false,
    comments: {"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},
    algolia: {
      appID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    },
    localsearch: {"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},
    path: '',
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}
  };
</script>

  <meta name="description" content="设备驱动模型对于 Linux 这样一个成熟、庞大、复杂的操作系统，代码的重用性非常重要，否则的话就会在Linux内核中存在大量无意义的重复代码。当前Linux使用设备(device)，总线(bus)，驱动(driver)模型。Linux设备驱动模型如下图所示。设备和驱动各司其职，设备干设备的活，驱动干驱动的活，总线将两者匹配起来。一个Linux设备和驱动都需要挂接在一种总线上，对于USB、I2C、">
<meta property="og:type" content="article">
<meta property="og:title" content="platform设备驱动">
<meta property="og:url" content="http://yoursite.com/2021/10/20/platform%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A%A8/index.html">
<meta property="og:site_name" content="SRCNN">
<meta property="og:description" content="设备驱动模型对于 Linux 这样一个成熟、庞大、复杂的操作系统，代码的重用性非常重要，否则的话就会在Linux内核中存在大量无意义的重复代码。当前Linux使用设备(device)，总线(bus)，驱动(driver)模型。Linux设备驱动模型如下图所示。设备和驱动各司其职，设备干设备的活，驱动干驱动的活，总线将两者匹配起来。一个Linux设备和驱动都需要挂接在一种总线上，对于USB、I2C、">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="http://yoursite.com/images/platform_driver.png">
<meta property="article:published_time" content="2021-10-20T14:39:00.000Z">
<meta property="article:modified_time" content="2022-01-01T12:22:57.718Z">
<meta property="article:author" content="Z.J. Jiang">
<meta property="article:tag" content="SISR">
<meta property="article:tag" content=" FH">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://yoursite.com/images/platform_driver.png">

<link rel="canonical" href="http://yoursite.com/2021/10/20/platform%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A%A8/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome: false,
    isPost: true
  };
</script>

  <title>platform设备驱动 | SRCNN</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-meta">

    <div>
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">SRCNN</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
        <p class="site-subtitle">SISR-FH</p>
  </div>

  <div class="site-nav-toggle">
    <div class="toggle" aria-label="Toggle navigation bar">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-fw fa-home"></i>Home</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-fw fa-tags"></i>Tags</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-fw fa-th"></i>Categories</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>Archives</a>

  </li>
  </ul>

</nav>
</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content">
            

  <div class="posts-expand">
      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block " lang="en">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2021/10/20/platform%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A%A8/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Z.J. Jiang">
      <meta itemprop="description" content="about the single image super-resolution and face hallucination">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="SRCNN">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          platform设备驱动
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">Posted on</span>

              <time title="Created: 2021-10-20 22:39:00" itemprop="dateCreated datePublished" datetime="2021-10-20T22:39:00+08:00">2021-10-20</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">Edited on</span>
                <time title="Modified: 2022-01-01 20:22:57" itemprop="dateModified" datetime="2022-01-01T20:22:57+08:00">2022-01-01</time>
              </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="设备驱动模型"><a href="#设备驱动模型" class="headerlink" title="设备驱动模型"></a>设备驱动模型</h1><p>对于 Linux 这样一个成熟、庞大、复杂的操作系统，代码的重用性非常重要，否则的话就会在Linux内核中存在大量无意义的重复代码。当前Linux使用设备(device)，总线(bus)，驱动(driver)模型。Linux设备驱动模型如下图所示。<br><img src="/images/platform_driver.png" class="[Linux驱动模型示意图]" title="[14] [6] " alt="title text"><br>设备和驱动各司其职，设备干设备的活，驱动干驱动的活，总线将两者匹配起来。一个Linux设备和驱动都需要挂接在一种总线上，对于USB、I2C、SPI等有物理总线直接的设备来说，没有任何问题，但是在SoC中有些外设是没有总线这个概念的，但是又要使用总线、驱动和设备模型该怎么办呢？因此，Linux发明了一种虚拟总线，称为platform总线。相应的设备称为platform_device，而驱动称为platform_driver。</p>
<h1 id="platform-driver"><a href="#platform-driver" class="headerlink" title="platform_driver"></a>platform_driver</h1><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">platform_driver</span> &#123;</span></span><br><span class="line">    <span class="keyword">int</span> (*probe)(struct platform_device *);</span><br><span class="line">    <span class="keyword">int</span> (*<span class="built_in">remove</span>)(struct platform_device *);</span><br><span class="line">    <span class="keyword">void</span> (*<span class="built_in">shutdown</span>)(struct platform_device *);</span><br><span class="line">    <span class="keyword">int</span> (*suspend)(struct platform_device *, <span class="keyword">pm_message_t</span> state);</span><br><span class="line">    <span class="keyword">int</span> (*resume)(struct platform_device *);</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">device_driver</span> <span class="title">driver</span>;</span></span><br><span class="line">    <span class="keyword">const</span> <span class="class"><span class="keyword">struct</span> <span class="title">platform_device_id</span> *<span class="title">id_table</span>;</span></span><br><span class="line">    <span class="keyword">bool</span> prevent_deferred_probe;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>platform driver 结构体包含了probe remove。这个结构体用于注册驱动到platform总线。</p>
<h1 id="platform-device"><a href="#platform-device" class="headerlink" title="platform_device"></a>platform_device</h1><p>platform device的结构体如下所示。platform device结构体用于描述硬件信息，通常有一个名称用于和驱动绑定，还有一个资源列表，比如内存和中断<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">platform_device</span> &#123;</span></span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span>    *name;</span><br><span class="line">    <span class="keyword">int</span>        id;</span><br><span class="line">    <span class="keyword">bool</span>        id_auto;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">device</span>    <span class="title">dev</span>;</span></span><br><span class="line">    u64        platform_dma_mask;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">device_dma_parameters</span> <span class="title">dma_parms</span>;</span></span><br><span class="line">    u32        num_resources;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">resource</span>    *<span class="title">resource</span>;</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> <span class="class"><span class="keyword">struct</span> <span class="title">platform_device_id</span>    *<span class="title">id_entry</span>;</span></span><br><span class="line">    <span class="keyword">char</span> *driver_override; <span class="comment">/* Driver name to force a match */</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/* MFD cell pointer */</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">mfd_cell</span> *<span class="title">mfd_cell</span>;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/* arch specific additions */</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">pdev_archdata</span>    <span class="title">archdata</span>;</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p>
<p>platform设备的资源由resource结构体描述。flags可以是IORESOURCE_MEM、IORESOURCE_IRQ类型。当flags是IORESOURCE_MEM时，start、end表示该platform_device占据的内存的起始地址和结束地址；当flags是IORESOURCE_IRQ时，表示该platform_device使用的中断号的开始值和结束值，如果使用了1个中断号，开始和结束值相同。<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">resource</span> &#123;</span></span><br><span class="line">    <span class="keyword">resource_size_t</span> start;  <span class="comment">// 表示资源的起始值，           </span></span><br><span class="line">    <span class="keyword">resource_size_t</span> <span class="built_in">end</span>;    <span class="comment">// 表示资源的最后一个字节的地址</span></span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span> *name;</span><br><span class="line">    <span class="keyword">unsigned</span> <span class="keyword">long</span> flags; <span class="comment">//资源的类型</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">resource</span> *<span class="title">parent</span>, *<span class="title">sibling</span>, *<span class="title">child</span>;</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p>
<h1 id="platform-bus-type"><a href="#platform-bus-type" class="headerlink" title="platform bus type"></a>platform bus type</h1><p>系统为platform总线定义了一个bus_type的实例platform_bus_type。需要重点关注<code>platform_match</code>函数，该函数就是驱动和设备的匹配函数。<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">bus_type</span> <span class="title">platform_bus_type</span> = &#123;</span></span><br><span class="line">    .name        = <span class="string">"platform"</span>,</span><br><span class="line">    .dev_groups    = platform_dev_groups,</span><br><span class="line">    .match        = platform_match,</span><br><span class="line">    .uevent        = platform_uevent,</span><br><span class="line">    .dma_configure    = platform_dma_configure,</span><br><span class="line">    .pm        = &amp;platform_dev_pm_ops,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">platform_match</span><span class="params">(struct device *dev, struct device_driver *drv)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">platform_device</span> *<span class="title">pdev</span> = <span class="title">to_platform_device</span>(<span class="title">dev</span>);</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">platform_driver</span> *<span class="title">pdrv</span> = <span class="title">to_platform_driver</span>(<span class="title">drv</span>);</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/* When driver_override is set, only bind to the matching driver */</span></span><br><span class="line">    <span class="keyword">if</span> (pdev-&gt;driver_override)</span><br><span class="line">        <span class="keyword">return</span> !<span class="built_in">strcmp</span>(pdev-&gt;driver_override, drv-&gt;name);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* Attempt an OF style match first */</span></span><br><span class="line">    <span class="keyword">if</span> (of_driver_match_device(dev, drv))</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* Then try ACPI style match */</span></span><br><span class="line">    <span class="keyword">if</span> (acpi_driver_match_device(dev, drv))</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* Then try to match against the id table */</span></span><br><span class="line">    <span class="keyword">if</span> (pdrv-&gt;id_table)</span><br><span class="line">        <span class="keyword">return</span> platform_match_id(pdrv-&gt;id_table, pdev) != <span class="literal">NULL</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* fall-back to driver name match */</span></span><br><span class="line">    <span class="keyword">return</span> (<span class="built_in">strcmp</span>(pdev-&gt;name, drv-&gt;name) == <span class="number">0</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>可以看出platform_match有四种匹配模式。一种是基于设备树风格的匹配；二是基于ACPI风格的匹配；三是ID表的匹配，platform_driver有一个id_table的变量；四是匹配platform_device设备名和驱动名。</p>
<h1 id="注册platform驱动"><a href="#注册platform驱动" class="headerlink" title="注册platform驱动"></a>注册platform驱动</h1><h2 id="注册设备"><a href="#注册设备" class="headerlink" title="注册设备"></a>注册设备</h2><p>platform_device_register函数可以注册设备.</p>
<h2 id="注册驱动"><a href="#注册驱动" class="headerlink" title="注册驱动"></a>注册驱动</h2><p>platform_driver_register函数可以注册驱动。</p>
<h1 id="match和probe函数的调用时机"><a href="#match和probe函数的调用时机" class="headerlink" title="match和probe函数的调用时机"></a>match和probe函数的调用时机</h1><p>下面的函数调用链展示了，设备和驱动何时通过match函数绑定到一起，以及何时执行驱动的probe函数。在调用<code>platform_driver_register</code>注册驱动时，会调用总线上的match函数，即platform_bus_type.match函数将驱动和设备绑定到一起，驱动和设备绑定成功之后，就会执行驱动的probe函数。<br><figure class="highlight xl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">platform_driver_register</span><br><span class="line">    __platform_driver_register</span><br><span class="line">        driver_register <span class="comment">// 注册驱动</span></span><br><span class="line">            bus_add_driver <span class="comment">// 将驱动添加到总线上</span></span><br><span class="line">                driver_attach <span class="comment">// 将驱动和设备绑定到一起</span></span><br><span class="line">                    __driver_attach</span><br><span class="line">                        driver_match_device</span><br><span class="line">                            <span class="function"><span class="title">drv</span>-&gt;</span><span class="function"><span class="title">bus</span>-&gt;</span>match <span class="comment">// 最后调用总线上的match函数，即platform_bus_type.match函数，如上所述，共有四种match方式</span></span><br><span class="line"></span><br><span class="line">                        device_driver_attach <span class="comment">// 将特定的驱动和设备关联到一起</span></span><br><span class="line">                            driver_probe_device <span class="comment">// 驱动检测到设备后调用probe函数。</span></span><br><span class="line">                                really_probe</span><br><span class="line">                                    <span class="function"><span class="title">drv</span>-&gt;</span>probe <span class="comment">// 调用驱动的probe函数</span></span><br></pre></td></tr></table></figure></p>
<h1 id="Example"><a href="#Example" class="headerlink" title="Example"></a>Example</h1><p>driver.c<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;linux/module.h&gt;    /* Needed by all modules */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;linux/kernel.h&gt;    /* Needed for KERN_INFO */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;linux/platform_device.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;linux/init.h&gt;        /* Needed for the macros */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> DRIVER_AUTHOR <span class="meta-string">"Jiang Zijin"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> DRIVER_DESC   <span class="meta-string">"A platform driver test"</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">pfd_driver_probe</span><span class="params">(struct platform_device *pdev)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    printk(KERN_INFO <span class="string">"platform driver probe\n"</span>);</span><br><span class="line">    <span class="comment">/* do something */</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">pfd_driver_remove</span><span class="params">(struct platform_device *pdev)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">/* do something */</span></span><br><span class="line">    printk(KERN_INFO <span class="string">"platform driver remove\n"</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="class"><span class="keyword">struct</span> <span class="title">platform_driver</span> <span class="title">pfd_driver</span> = &#123;</span></span><br><span class="line">    .driver = &#123;</span><br><span class="line">        .name    = <span class="string">"pfd_driver_test"</span>,</span><br><span class="line">        .owner = THIS_MODULE,</span><br><span class="line">    &#125;,</span><br><span class="line">    .probe        = pfd_driver_probe,</span><br><span class="line">    .<span class="built_in">remove</span>        = pfd_driver_remove,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* module_driver(__platform_driver, platform_driver_register, \</span></span><br><span class="line"><span class="comment">            platform_driver_unregister) */</span></span><br><span class="line"><span class="comment">/* 调用platform_driver_register注册驱动 */</span></span><br><span class="line">module_platform_driver(pfd_driver);</span><br><span class="line"></span><br><span class="line">MODULE_LICENSE(<span class="string">"GPL"</span>);</span><br><span class="line">MODULE_AUTHOR(DRIVER_AUTHOR);</span><br><span class="line">MODULE_DESCRIPTION(DRIVER_DESC);</span><br></pre></td></tr></table></figure></p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;linux/module.h&gt;    /* Needed by all modules */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;linux/kernel.h&gt;    /* Needed for KERN_INFO */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;linux/platform_device.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;linux/init.h&gt;        /* Needed for the macros */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> DRIVER_AUTHOR <span class="meta-string">"Jiang Zijin"</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">test_pfd_release</span><span class="params">(struct device *dev)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="class"><span class="keyword">struct</span> <span class="title">platform_device</span> <span class="title">test_pdev</span> = </span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    .name = <span class="string">"pfd_driver_test"</span>,</span><br><span class="line">    .id = <span class="number">-1</span>,</span><br><span class="line">    .dev.<span class="built_in">release</span> = test_pfd_release,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">int</span> __<span class="function">init <span class="title">test_pdev_init</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    printk(KERN_INFO <span class="string">"platform device init\n"</span>);</span><br><span class="line">    <span class="keyword">return</span> platform_device_register(&amp;test_pdev);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">void</span> __<span class="function"><span class="built_in">exit</span> <span class="title">test_pdev_exit</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    printk(KERN_INFO <span class="string">"platform device exit\n"</span>);</span><br><span class="line">    platform_device_unregister(&amp;test_pdev);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">module_init(test_pdev_init);</span><br><span class="line">module_exit(test_pdev_exit)</span><br><span class="line"></span><br><span class="line">MODULE_LICENSE(<span class="string">"GPL"</span>);</span><br><span class="line">MODULE_AUTHOR(DRIVER_AUTHOR);</span><br></pre></td></tr></table></figure>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">KVERS = $(shell uname -r)</span><br><span class="line"></span><br><span class="line"># Kernel modules</span><br><span class="line">obj-m += pfd_driver.o pfd_device.o</span><br><span class="line"></span><br><span class="line"># Specify flags <span class="keyword">for</span> the <span class="keyword">module</span> compilation.</span><br><span class="line">EXTRA_CFLAGS=-g -O0</span><br><span class="line"></span><br><span class="line">build: kernel_modules</span><br><span class="line"></span><br><span class="line">kernel_modules:</span><br><span class="line">4make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules</span><br><span class="line"></span><br><span class="line">clean:</span><br><span class="line">4make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean</span><br></pre></td></tr></table></figure>
<p>执行make即可成功编译出<code>pfd_driver.ko</code>和<code>pfd_device.ko</code>两个内核文件。可使用insmode加载这两个内核文件。<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">insmod</span> <span class="selector-tag">pfd_device</span><span class="selector-class">.ko</span></span><br><span class="line"><span class="selector-tag">insmod</span> <span class="selector-tag">pfd_driver</span><span class="selector-class">.ko</span></span><br><span class="line"><span class="selector-attr">[  556.856482]</span> <span class="selector-tag">platform</span> <span class="selector-tag">device</span> <span class="selector-tag">init</span></span><br><span class="line"><span class="selector-attr">[  561.823973]</span> <span class="selector-tag">platform</span> <span class="selector-tag">driver</span> <span class="selector-tag">probe</span></span><br></pre></td></tr></table></figure><br>加载后使用<code>demsg</code>打印内核信息即可看到<code>platform device init</code>和<code>platform driver probe</code>的打印。这说明platform设备和驱动绑定到一起了，绑定成功之后就执行驱动的probe函数。</p>
<p>ok，这个例子似乎有点简单，加点资源进去。加上一点内存和中断号的资源，并在驱动的probe函数中使用。在驱动中很容易就可以使用到这些资源了。</p>
<p>TODO： 把相应代码加上。</p>
<p>[  432.948791] platform device init<br>[  437.752513] platform driver probe<br>[  437.752517] mem start addr = 12340000<br>[  437.752520] irq num = 100</p>
<h1 id="设备树"><a href="#设备树" class="headerlink" title="设备树"></a>设备树</h1><p>从上面的例子可以发现，platform device可能除了一些resource资源不一样外，其他部分大差不差的。如果每来一个设备都需要写一个xxx_device.c，那么内核代码就会很臃肿。因此引入了描述硬件的数据结构—设备树。采用设备树之后，许多硬件的细节可以直接通过它传递给Linux，而不再需要在内核中进行大量的冗余编码。</p>
<p>本文不对设备树进行过多介绍，仅展示使用设备树之后的便利性。<br>上述的例子中，我们可以把device相关的代码改用dts实现，只需要在dts中正确配置即可，无需在写那么多的设备代码了。在设备和驱动match过程中，通过相应的dts的接口match上。</p>
<h1 id="dts方式的match"><a href="#dts方式的match" class="headerlink" title="dts方式的match"></a>dts方式的match</h1><figure class="highlight sqf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">of_driver_match_device <span class="comment">// 驱动的of_match_table是否match上了相应的设备</span></span><br><span class="line">    of_match_device</span><br><span class="line">        of_match_node</span><br><span class="line">            <span class="variable">__of_match_node</span></span><br><span class="line">                <span class="variable">__of_device_is_compatible</span></span><br><span class="line">                    <span class="variable">__of_find_property</span> <span class="comment">// prop = __of_find_property(device, "compatible", NULL); 最终是利用dts的"compatible"来匹配的，即设备树加载之后，内核会自动把设备树节点转换成platform_device这种格式，同时把名字放到of_node这个地方。</span></span><br></pre></td></tr></table></figure>
<h1 id="改写example"><a href="#改写example" class="headerlink" title="改写example"></a>改写example</h1><p>设备树的详细内容这里就不再展开介绍了，下面将上述例子的device部分改写成设备树实现，展示一下使用设备树的便利性。<br>TODO: 把代码贴上去。直接该内核的。 已完成，放到公司内网中了。<br>参考：<br>《Linux设备驱动开发详解》<br><a href="https://zhuanlan.zhihu.com/p/134180200" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/134180200</a><br><a href="https://biscuitos.github.io/blog/DTS/#:~:text=DTS%20%E6%98%AF%E4%B8%BA%20Linux%20%E6%8F%90%E4%BE%9B%E4%B8%80%E7%A7%8D%E7%A1%AC%E4%BB%B6%E4%BF%A1%E6%81%AF%E7%9A%84%E6%8F%8F%E8%BF%B0%E6%96%B9%E6%B3%95%EF%BC%8C%E4%BB%A5%E6%AD%A4%E4%BB%A3%E6%9B%BF%E6%BA%90%E7%A0%81%E4%B8%AD%E7%9A%84%20%E7%A1%AC%E4%BB%B6%E7%BC%96%E7%A0%81%20%28hard%20code%29%E3%80%82%20DTS,%28OF%29.%20%E5%9C%A8%20Linux%202.6%20%E4%B8%AD%EF%BC%8C%20ARM%20%E6%9E%B6%E6%9E%84%E7%9A%84%E6%9D%BF%E7%BA%A7%E7%A1%AC%E4%BB%B6%E7%BB%86%E8%8A%82%E8%BF%87%E5%A4%9A%E7%9A%84%E8%A2%AB%E7%A1%AC%E7%BC%96%E7%A0%81%E5%9C%A8%20arch%2Farm%2Fplat-xxx" target="_blank" rel="noopener">https://biscuitos.github.io/blog/DTS/#:~:text=DTS%20%E6%98%AF%E4%B8%BA%20Linux%20%E6%8F%90%E4%BE%9B%E4%B8%80%E7%A7%8D%E7%A1%AC%E4%BB%B6%E4%BF%A1%E6%81%AF%E7%9A%84%E6%8F%8F%E8%BF%B0%E6%96%B9%E6%B3%95%EF%BC%8C%E4%BB%A5%E6%AD%A4%E4%BB%A3%E6%9B%BF%E6%BA%90%E7%A0%81%E4%B8%AD%E7%9A%84%20%E7%A1%AC%E4%BB%B6%E7%BC%96%E7%A0%81%20%28hard%20code%29%E3%80%82%20DTS,%28OF%29.%20%E5%9C%A8%20Linux%202.6%20%E4%B8%AD%EF%BC%8C%20ARM%20%E6%9E%B6%E6%9E%84%E7%9A%84%E6%9D%BF%E7%BA%A7%E7%A1%AC%E4%BB%B6%E7%BB%86%E8%8A%82%E8%BF%87%E5%A4%9A%E7%9A%84%E8%A2%AB%E7%A1%AC%E7%BC%96%E7%A0%81%E5%9C%A8%20arch%2Farm%2Fplat-xxx</a></p>
<p>platform驱动转成dts<br><a href="https://blog.csdn.net/zqixiao_09/article/details/50889458" target="_blank" rel="noopener">https://blog.csdn.net/zqixiao_09/article/details/50889458</a></p>
<p>source code:<br><a href="https://gitee.com/jzijin/linux_driver" target="_blank" rel="noopener">https://gitee.com/jzijin/linux_driver</a></p>

    </div>

    
    
    

      <footer class="post-footer">

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2021/09/07/%E7%94%9F%E6%B6%AF%E8%A7%84%E5%88%92-%E7%92%80%E7%92%A8%E4%BA%BA%E7%94%9F/" rel="prev" title="生涯规划 璀璨人生">
      <i class="fa fa-chevron-left"></i> 生涯规划 璀璨人生
    </a></div>
      <div class="post-nav-item">
    <a href="/2022/01/02/csapp/" rel="next" title="csapp">
      csapp <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  

  </div>


          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let activeClass = CONFIG.comments.activeClass;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          Table of Contents
        </li>
        <li class="sidebar-nav-overview">
          Overview
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#设备驱动模型"><span class="nav-number">1.</span> <span class="nav-text">设备驱动模型</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#platform-driver"><span class="nav-number">2.</span> <span class="nav-text">platform_driver</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#platform-device"><span class="nav-number">3.</span> <span class="nav-text">platform_device</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#platform-bus-type"><span class="nav-number">4.</span> <span class="nav-text">platform bus type</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#注册platform驱动"><span class="nav-number">5.</span> <span class="nav-text">注册platform驱动</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#注册设备"><span class="nav-number">5.1.</span> <span class="nav-text">注册设备</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#注册驱动"><span class="nav-number">5.2.</span> <span class="nav-text">注册驱动</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#match和probe函数的调用时机"><span class="nav-number">6.</span> <span class="nav-text">match和probe函数的调用时机</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#Example"><span class="nav-number">7.</span> <span class="nav-text">Example</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#设备树"><span class="nav-number">8.</span> <span class="nav-text">设备树</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#dts方式的match"><span class="nav-number">9.</span> <span class="nav-text">dts方式的match</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#改写example"><span class="nav-number">10.</span> <span class="nav-text">改写example</span></a></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">Z.J. Jiang</p>
  <div class="site-description" itemprop="description">about the single image super-resolution and face hallucination</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">42</span>
          <span class="site-state-item-name">posts</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">11</span>
        <span class="site-state-item-name">categories</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">1</span>
        <span class="site-state-item-name">tags</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/jzijin" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;jzijin" rel="noopener" target="_blank"><i class="fa fa-fw fa-github"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="/atom.xml" title="RSS → &#x2F;atom.xml"><i class="fa fa-fw fa-rss"></i>RSS</a>
      </span>
  </div>


  <div class="links-of-blogroll motion-element">
    <div class="links-of-blogroll-title">
      <i class="fa fa-fw fa-link"></i>
      Links
    </div>
    <ul class="links-of-blogroll-list">
        <li class="links-of-blogroll-item">
          <a href="http://www.njust.edu.cn/" title="http:&#x2F;&#x2F;www.njust.edu.cn" rel="noopener" target="_blank">南京理工大学</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="http://ehall.njust.edu.cn/new/index.html" title="http:&#x2F;&#x2F;ehall.njust.edu.cn&#x2F;new&#x2F;index.html" rel="noopener" target="_blank">南京理工大学智慧服务</a>
        </li>
        <li class="links-of-blogroll-item">
          <a href="http://lib.njust.edu.cn/" title="http:&#x2F;&#x2F;lib.njust.edu.cn&#x2F;" rel="noopener" target="_blank">南京理工大学图书馆</a>
        </li>
    </ul>
  </div>

      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Z.J. Jiang</span>
</div>
  <div class="powered-by">Powered by <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> v4.2.0
  </div>
  <span class="post-meta-divider">|</span>
  <div class="theme-info">Theme – <a href="https://pisces.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Pisces</a> v7.6.0
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

  

</body>
</html>
